package weibo4j.crawler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import weibo4j.Status;
import weibo4j.User;
import weibo4j.Weibo;
import weibo4j.WeiboException;
import weibo4j.database.DataBaseUtil;

public class UserInfoCrawler extends CrawlerBase {
	private long seedId;
	// Database Connection
	private Connection userInfoConn;
	private Connection statusConn;
	private QueueBase queue4UserInfo;
	private QueueBase queue4Status4RetweetedStatus;
	private QueueBase queue4Status4Comment;
	
	private StatusCrawler statusCrawler;
	private CommentCrawler commentCrawler;
	private int queueBufMaxLength;
	
	public List<QueueBase> getAllQueue(){
		List<QueueBase> res = new ArrayList<QueueBase>();
		res.add(queue4UserInfo);
		res.add(queue4Status4RetweetedStatus);
		res.add(queue4Status4Comment);
		return res;
	}
	
	public UserInfoCrawler(Weibo weibo, int queueBufMaxLength) {
		super(weibo);
		seedId = -1;
		userInfoConn = DataBaseUtil.getDefaultConnection();
		statusConn = DataBaseUtil.getDefaultConnection();
		
		commentCrawler = new CommentCrawler(weibo);
		statusCrawler = new StatusCrawler(weibo);
		
		this.queueBufMaxLength = queueBufMaxLength;
		
	}

	public void init(long userId) throws Exception {
		this.seedId = userId;
		this.queue4Status4RetweetedStatus = new QueueBase(new QueueBuffer(QueueBuffer.STATUS, 
				DataBaseUtil.getDefaultConnection()), queueBufMaxLength);
		this.queue4Status4Comment = new QueueBase(new QueueBuffer(QueueBuffer.COMMENT, 
				DataBaseUtil.getDefaultConnection()), queueBufMaxLength);
		this.queue4UserInfo = new QueueBase(new QueueBuffer(QueueBuffer.USER, 
				DataBaseUtil.getDefaultConnection()), queueBufMaxLength);
		commentCrawler.init(this, queue4Status4Comment);
		statusCrawler.init(this, queue4Status4RetweetedStatus);
		
		if (queue4UserInfo.getLength() == 0){
			queue4UserInfo.add(new UserInfoQueueRecord(seedId,
					myDateTimeFormat.format(new Date())));
		}
		else{
			queue4UserInfo.loadDBDataIntoMem();
			queue4Status4Comment.loadDBDataIntoMem();
			queue4Status4RetweetedStatus.loadDBDataIntoMem();
		}
	}

	private void doVisit(long userId) throws Exception {
		int[] idss = super.getAllFriendsIdsByUserId(userId);
		for (int i = 0; i < idss.length; i++) {
			queue4UserInfo.add(new UserInfoQueueRecord(idss[i],
					myDateTimeFormat.format(new Date())));
		}

		idss = super.getAllFollowersIdsByUserId(userId);
		for (int i = 0; i < idss.length; i++) {
			queue4UserInfo.add(new UserInfoQueueRecord(idss[i],
					myDateTimeFormat.format(new Date())));
		}
	}

	public void ready() {
		commentCrawler.start();
		statusCrawler.start();			
	}
	
	public synchronized void go() {
	      notifyAll();
	}
	
	public void prepare(CrawlerBase crawler) throws InterruptedException, Exception {      
		if (crawler instanceof StatusCrawler) {
			synchronized (this) {
				while (queue4Status4RetweetedStatus.getLength() == 0)
					wait();
			}
		}
		if (crawler instanceof CommentCrawler) {
			synchronized (this) {
				while (queue4Status4Comment.getLength() == 0)
					wait();
			}
		}
	}
	
	public void run() {
		User u = null;
		try {
			System.out.println("User crawler is starting ...");
			ready();			
			UserInfoQueueRecord rec = null;
			while (queue4UserInfo.getLength() != 0 ) {
//				synchronized(this){
//					if(CrawlerMaster.exitFlag){
//						queue4UserInfo.saveMemDataIntoDB();
//						System.out.println("here");
//						return;
//					}
//				}
				
				rec = (UserInfoQueueRecord) queue4UserInfo.poll();
				System.err.println(rec.toString());

				u = super.getUserInfoByUserId(rec.userId);

				// save user info into database
				DataBaseUtil.executeStatement(userInfoConn, u.getUserInfoSQLString("utf-8"));
				//DataBaseUtil.insert(userInfoConn, "users", User.getFieldString(), User.getEmptyValueString(),
				//		u.getRecord("utf-8"));
				
				//System.err.println(u.toString() + '\n'
				//		+ u.getUserInfoSQLString("utf-8"));

				// save status into database;
				long statusId = u.getCurrentStatus().getId();
				queue4Status4RetweetedStatus.add(new StatusQueueRecord(
						statusId, myDateTimeFormat.format(new Date())));
				queue4Status4Comment.add(new CommentQueueRecord(statusId,
						myDateTimeFormat.format(new Date())));
				
				DataBaseUtil.executeStatement(statusConn, u.getCurrentStatus().getStatusSQLString(u, "utf-8"));
				//DataBaseUtil.insert(statusConn, "statuses",	Status.getFieldString(), Status.getEmptyValueString(),
				//		u.getCurrentStatus().getRecord(u, "utf-8"));
				//System.err.println(u.getCurrentStatus().toString() + '\n'
				//		+ u.getCurrentStatus().getStatusSQLString(u, "utf-8"));

				// if the status above is retweeted_status, save the
				// retweed_status id into database.
				if (u.getCurrentStatus().isRetweet()) {
					statusId = u.getCurrentStatus().getRetweetStauts()
							.getRetweetId();
					queue4Status4RetweetedStatus.add(new StatusQueueRecord(
							statusId, myDateTimeFormat.format(new Date())));
					queue4Status4Comment.add(new CommentQueueRecord(statusId,
							myDateTimeFormat.format(new Date())));
				}	
				go();
				doVisit(rec.userId);				
				adjustFreq();
				System.out.println("working... UserInfo queue's size:"
						+ queue4UserInfo.getLength());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}
